package edu.vt.ece.rt.quorum.messsages.types;

import org.jgroups.Address;
import org.jgroups.Message;

import edu.vt.ece.rt.dstm.ContextDelegator;
import edu.vt.ece.rt.dstm.QObject;
import edu.vt.ece.rt.dstm.TMProxy;
import edu.vt.ece.rt.quorum.ClustersManager;
import edu.vt.ece.rt.quorum.Resource;
import edu.vt.ece.rt.quorum.messsages.QMessage;
import edu.vt.ece.rt.quorum.messsages.QMessage.MessageType;
import edu.vt.ece.rt.quorum.util.Names;
import edu.vt.ece.rt.util.Logger.Logger;

/*
 * Read Request to all the nodes in read Quorum
 * @author Sudhanshu
 */

public class ReadRequest extends QMessage implements Runnable {
	String Id;			//Specify the Object Id to be received
	Long txnId; 		//Specify the transaction number, Can be Converted to Context Class, if some MetaData required
	boolean read;		//Specify read or write 
	int requesterID;		//Specify the cluster on which response will be unicast back

	public ReadRequest(String id, Long tid, boolean rw, int rid) {
		super(MessageType.ReadRequest);
		Id = id;
		txnId = tid;
		read = rw;
		requesterID = rid;
	}
	
	@Override
	public void run() {
		//Get Object
		Logger.debug("Running the "+ (read?"Read":"write")+" Request of "+ Id + " for " + txnId+ " from "+requesterID);
		QObject qObj = Resource.getQObject(Id);
		
		if(qObj == null){
			System.err.println("Issue with publishing, Object id "+Id+" not found");
			return;
		}
		
		//Add Context to potential read-write list
		if(read == true){		//Read request
			Resource.addPR(Id, ContextDelegator.getContext(txnId));
			ContextDelegator.getContext(txnId).addToReadSet(qObj);
			Logger.debug("Added "+txnId+ " as potential reader of "+qObj.getId());
		}
		else{
			Resource.addPW(Id, ContextDelegator.getContext(txnId));
			ContextDelegator.getContext(txnId).addToWriteSet(qObj);
			Logger.debug("Added "+txnId+ " as potential writer of "+qObj.getId());
		}

		//Send back the response to node
		try {
			ClustersManager.getCluster(requesterID+Names.readQuorum).send(new Message(getSrcAddr(), new ReadResponse(Id, txnId, qObj, read)));
			
			//Use when sending write request to all in write quorum
//			if(read)
//				ClustersManager.getCluster(requesterID+Names.readQuorum).send(new Message(getSrcAddr(), new ReadResponse(Id, txnId, qObj, read)));
//			else	
//				ClustersManager.getCluster(requesterID+Names.writeQuorum).send(new Message(getSrcAddr(), new ReadResponse(Id, txnId, qObj, read)));
	
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}	
}
